package com.doctcloud.common.core.utils;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * 拼音工具类，基于 pinyin4j 实现汉字转拼音功能
 * 支持：拼音首字母、全拼（无声调）、全拼（带声调）
 */
public class PinYinUtils {

    /**
     * 匹配简繁体汉字的正则表达式（\u4E00-\u9FFF 包含全部中日韩汉字）
     */
    private static final String CHINESE_REGEX = "^[\\u4E00-\\u9FFF]+$";

    /**
     * 无声调的拼音格式（大写）
     */
    private static final HanyuPinyinOutputFormat FORMAT_WITHOUT_TONE;

    /**
     * 带声调的拼音格式（大写，韵母用 Unicode 表示，如 ü）
     */
    private static final HanyuPinyinOutputFormat FORMAT_WITH_TONE;

    static {
        // 初始化无声调格式
        FORMAT_WITHOUT_TONE = new HanyuPinyinOutputFormat();
        FORMAT_WITHOUT_TONE.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        FORMAT_WITHOUT_TONE.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        FORMAT_WITHOUT_TONE.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);

        // 初始化带声调格式
        FORMAT_WITH_TONE = new HanyuPinyinOutputFormat();
        FORMAT_WITH_TONE.setToneType(HanyuPinyinToneType.WITH_TONE_MARK);
        FORMAT_WITH_TONE.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        FORMAT_WITH_TONE.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
    }

    /**
     * 私有化构造方法，禁止实例化
     */
    private PinYinUtils() {
        throw new AssertionError("工具类不允许实例化");
    }

    /**
     * 获取拼音首字母（大写），非汉字字符会被忽略
     * 例：何宇涛 → HYT
     *
     * @param inputStr 输入字符串（支持汉字，非汉字会被过滤）
     * @return 首字母拼接的字符串，若输入为空则返回空串
     */
    public static String getPYHead(String inputStr) {
        if (isEmpty(inputStr)) {
            return "";
        }
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < inputStr.length(); i++) {
            char c = inputStr.charAt(i);
            String charStr = Character.toString(c);
            // 仅处理汉字
            if (charStr.matches(CHINESE_REGEX)) {
                String pinyin = convertCharToPinyin(c, FORMAT_WITHOUT_TONE);
                if (!isEmpty(pinyin)) {
                    buffer.append(pinyin.charAt(0)); // 取首字母
                }
            }
        }
        return buffer.toString();
    }

    /**
     * 获取全拼（大写，无声调），非汉字字符会被保留
     * 例：何宇涛 → HEYUTAO
     *
     * @param inputStr 输入字符串
     * @return 全拼字符串，若输入为空则返回空串
     */
    public static String getFullPinyin(String inputStr) {
        return convertToPinyin(inputStr, FORMAT_WITHOUT_TONE, false);
    }

    /**
     * 获取全拼（大写，带声调），非汉字字符会被保留
     * 例：何宇涛 → HÉYǓTĀO
     *
     * @param inputStr 输入字符串
     * @return 带声调的全拼字符串，若输入为空则返回空串
     */
    public static String getFullPinyinWithTone(String inputStr) {
        return convertToPinyin(inputStr, FORMAT_WITH_TONE, false);
    }

    /**
     * 通用拼音转换方法
     *
     * @param inputStr    输入字符串
     * @param format      拼音格式
     * @param ignoreNonHan 是否忽略非汉字字符（true：忽略，false：保留）
     * @return 转换后的拼音字符串
     */
    private static String convertToPinyin(String inputStr, HanyuPinyinOutputFormat format, boolean ignoreNonHan) {
        if (isEmpty(inputStr)) {
            return "";
        }
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < inputStr.length(); i++) {
            char c = inputStr.charAt(i);
            String charStr = Character.toString(c);
            if (charStr.matches(CHINESE_REGEX)) {
                // 汉字：转换为拼音
                buffer.append(convertCharToPinyin(c, format));
            } else if (!ignoreNonHan) {
                // 非汉字：保留（除非需要忽略）
                buffer.append(c);
            }
        }
        return buffer.toString();
    }

    /**
     * 将单个汉字转换为拼音
     * 处理多音字：默认取第一个拼音（可根据需求扩展为自定义策略）
     *
     * @param c      汉字字符
     * @param format 拼音格式
     * @return 拼音字符串（大写），若转换失败则返回空串
     */
    private static String convertCharToPinyin(char c, HanyuPinyinOutputFormat format) {
        try {
            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
            // 多音字取第一个，非汉字可能返回 null
            if (pinyinArray != null && pinyinArray.length > 0) {
                return pinyinArray[0];
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            // 格式配置错误（理论上不会发生，因格式在静态块中已固定）
            throw new IllegalArgumentException("拼音格式配置错误", e);
        }
        return "";
    }

    /**
     * 判断字符串是否为空（null 或空串）
     */
    private static boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }
}